import { ElementRef } from "@angular/core";
import { PerspectiveCamera, Scene, Vector2, WebGLRenderer } from "three";
import { InsideScene } from "../scene/inside";
import { OutsideScene } from "../scene/outside";
import { ThreeRenderer } from "../three/renderer";
import { degToRad } from "three/src/math/MathUtils.js";
import { BaseRaycaster } from "../raycaster/base";
import { Perspective } from "../camera/perspective";


export class SphereRenderer {

    private mouse = new Vector2();

    private camera: PerspectiveCamera =  new PerspectiveCamera;
    private scene: Scene;
    private renderer: WebGLRenderer;

    private perspective = new Perspective();
    private threeRenderer = new ThreeRenderer();
    private baseRaycaster = new BaseRaycaster();
    private insideScene = new InsideScene();
    private outsideScene = new OutsideScene();
    private elementRef!: ElementRef;

    private isUserInteracting = false;
    private onPointerDownPointerX = 0;
    private onPointerDownPointerY = 0;
    private onPointerDownLon = 0;
    private onPointerDownLat = 0;
    private lon = 0;
    private lat = 0;

    constructor() {
        this.scene = this.outsideScene.create()
        this.renderer = this.threeRenderer.webGL()
    }

    init(elementRef: ElementRef) {
        this.elementRef = elementRef;
        this.camera = this.perspective.init(75, this.elementRef.nativeElement.offsetWidth / this.elementRef.nativeElement.offsetHeight, 1, 1100)
        this.renderer.setPixelRatio(1);
        this.renderer.setSize(this.elementRef.nativeElement.offsetWidth, this.elementRef.nativeElement.offsetHeight);
        return this.renderer;
    }

    animate() {
        requestAnimationFrame(this.animate.bind(this));
        this.updateByMouse()
        this.renderer.render(this.scene, this.camera);
    }

    onMouseDown(event: MouseEvent) {
        this.isUserInteracting = true;
        this.onPointerDownPointerX = event.clientX;
        this.onPointerDownPointerY = event.clientY;
        this.onPointerDownLon = this.lon;
        this.onPointerDownLat = this.lat;

        this.baseRaycaster.setFromCamera(this.mouse, this.camera)
        const intersection = this.baseRaycaster.intersectObjects(this.scene.children);

        // 这里可以添加更多的逻辑，比如根据模型的name做不同的处理
        if (intersection.object.name === 'point_1_outside_car') {
            console.warn('不在车里')
        } else if (intersection.object.name === 'point_2_outside_people') {
            console.warn('不在人群中')
        } else if (intersection.object.name === 'point_0_outside_house') {
            console.warn('屋里可以检查下')
            this.switchScene('point_0_outside_house')
        } else if (intersection.object.name === 'point_3_inside_eating_room') {
            console.warn('不在厨房')
        } else if (intersection.object.name === 'point_4_inside_bed_room') {
            console.warn('小偷在这里')
            this.insideScene.addMurderer()
        } else if (intersection.object.name === 'point_5_inside_back') {
            console.warn('返回广场')
            this.switchScene()
        }

    }
    onMouseMove(event: MouseEvent) {
        this.mouse.x = (event.clientX / this.elementRef.nativeElement.offsetWidth) * 2 - 1;
        this.mouse.y = -(event.clientY / this.elementRef.nativeElement.offsetHeight) * 2 + 1;

        if (this.isUserInteracting === true) {
            this.lon = (this.onPointerDownPointerX - event.clientX) * 0.1 + this.onPointerDownLon;
            this.lat = (event.clientY - this.onPointerDownPointerY) * 0.1 + this.onPointerDownLat;
        }
    }
    onMouseUp(event: MouseEvent) {
        this.isUserInteracting = false;
    }
    onMouseWheel(event: WheelEvent) {
        this.camera.fov += event.deltaY * 0.05;
        if (this.camera.fov < 20) {
            this.camera.fov = 20
        } else if (this.camera.fov > 100) {
            this.camera.fov = 100
        }
        this.camera.updateProjectionMatrix();
    }

    onWindowResize() {
        this.camera.aspect = this.elementRef.nativeElement.offsetWidth / this.elementRef.nativeElement.offsetHeight;
        this.camera.updateProjectionMatrix();
        this.renderer.setSize(this.elementRef.nativeElement.offsetWidth, this.elementRef.nativeElement.offsetHeight);
    }

    //捕捉鼠标
    updateByMouse() {
        this.lat = Math.max(- 85, Math.min(85, this.lat));
        const phi = degToRad(90 - this.lat);
        const theta = degToRad(this.lon);

        let x = 500 * Math.sin(phi) * Math.cos(theta);
        let y = 500 * Math.cos(phi);
        let z = 500 * Math.sin(phi) * Math.sin(theta);
        this.camera.lookAt(x, y, z);
    }

    switchScene(text?: string) {
        if (text === 'point_0_outside_house') {
            this.scene = this.insideScene.create();
        } else {
            this.scene = this.outsideScene.create();
        }
    }

}